package com.colabo.j2ee.web.oaf.orgnization.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.colabo.j2ee.web.core.exception.CommonException;
import com.colabo.j2ee.web.core.exception.ServiceException;
import com.colabo.j2ee.web.core.persistence.HqlWrapper;
import com.colabo.j2ee.web.core.pkgenerator.IPKGenerator;
import com.colabo.j2ee.web.core.servertime.IServerTime;
import com.colabo.j2ee.web.core.service.impl.DefaultServiceImpl;
import com.colabo.j2ee.web.core.util.PropertyUtil;
import com.colabo.j2ee.web.core.util.StringUtil;
import com.colabo.j2ee.web.core.vo.SessionUserHolder;
import com.colabo.j2ee.web.oaf.common.AppConstants;
import com.colabo.j2ee.web.oaf.monitorperspective.ILogDataService;
import com.colabo.j2ee.web.oaf.orgnization.IPositionService;
import com.colabo.j2ee.web.oaf.orgnization.IRoleService;
import com.colabo.j2ee.web.oaf.orgnization.model.IPDutyVO;
import com.colabo.j2ee.web.oaf.orgnization.model.IPPositionVO;
import com.colabo.j2ee.web.oaf.orgnization.model.SCUserProfileVO;
import com.colabo.j2ee.web.oaf.orgnization.model.SCUnitProfileVO;
import com.colabo.j2ee.web.oaf.vo.IPAuditLogVO;

public class PositionServiceImpl extends DefaultServiceImpl implements IPositionService {
	private Log logger = LogFactory.getLog(PositionServiceImpl.class);
	private static final String POSITION_SAVE_EXIST = "exist";
	private static final String POSITION__SAVE_SUCCESS = "true";
	private static final String POSITION__SAVE_FAILE = "false";	
	private ILogDataService logDataService = null; 
	private static final String MODEL_Name = AppConstants.MSG_INFO_APP_3001;
	
	public IPPositionVO getPositionByPositionId(String positionid) throws ServiceException {
		return (IPPositionVO) findByID_Hibernate_Get(IPPositionVO.class, positionid);
	}

	public List getPositionsByUnit(SCUnitProfileVO unit) throws ServiceException {
		return getPositionsByUnit(unit, 0, 9999);
	}

	public List getPositionsByUnit(SCUnitProfileVO unit, int offset, int pageSize) throws ServiceException {
		if (unit != null) {
			return find_iBatis("org.getPositionsByUnit", unit, offset, pageSize);
		}
		return find_iBatis("org.getAllPositions", null, offset, pageSize);
	}

	public int getPositionCountByUnit(SCUnitProfileVO unit) throws ServiceException {
		List countList;
		if (unit != null) {
			countList = find_iBatis("org.getPositionCountByUnit", unit);
		} else {
			countList = find_iBatis("org.getAllPositionCount", null);
		}

		if (countList != null && !countList.isEmpty()) {
			return ((Integer) countList.get(0)).intValue();
		}
		return 0;
	}

	public String save(IPPositionVO positionVo) throws ServiceException {
		IServerTime serverTime = (IServerTime) getBean(IServerTime.BEAN_ID);
		try {
			positionVo.setCreatedTimestamp(serverTime.getServerDateTime());
			checkPosition(positionVo);
		} catch (CommonException e) {
			return POSITION__SAVE_FAILE;
		}
		if(isExist(positionVo.getPositionCode())){
			return POSITION_SAVE_EXIST;
		}
		super.save_Hibernate_Object(positionVo);
		SessionUserHolder suser = (SessionUserHolder)getBean("sessionUserHolder");
		logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_ORG_MAINTAIN,  IPAuditLogVO.OP_CODE_SAVE, suser.getStaffId(), suser
				.getLoginIp(), PropertyUtil
				.getPropertyByKey(MODEL_Name) + IPAuditLogVO.SEPARATE + positionVo.getPositionid()+IPAuditLogVO.SEPARATE+positionVo.getPositionName());
		return POSITION__SAVE_SUCCESS;
	}

	private void checkPosition(IPPositionVO positionVo) {
		if (positionVo.getDelFlag() == null) {
			positionVo.setDelFlag("n");
		}

		if (positionVo.getRole() != null) {
			String roleid = positionVo.getRole().getRoleid();
			if (roleid == null || "".equals(roleid)) {
				positionVo.setRole(null);
			}
		}

		if (positionVo.getStatus() == null) {
			positionVo.setStatus(IPPositionVO.STATUS_DEFAULT);
		}

		if (positionVo.getType() == null) {
			positionVo.setType(IPPositionVO.TYPE_DEFAULT);
		}
		if (positionVo.getKind() == null) {
			positionVo.setKind(IPPositionVO.KIND_DEFAULT);
		}
		if (positionVo.getDelFlag() == null) {
			positionVo.setDelFlag(IPPositionVO.DEL_FLAG_NORMAL);
		}
	}

	public IPPositionVO saveDefaultPosition(SCUnitProfileVO unitVo) throws ServiceException {
		IPPositionVO positionVo = new IPPositionVO();
		// TODO 国际化
		positionVo.setPositionid("defaultPos" + unitVo.getLogicalKey());
		positionVo.setPositionName(PropertyUtil
				.getPropertyByKey(AppConstants.MSG_INFO_APP_3005));
		positionVo.setKind(IPPositionVO.TYPE_VIRTUAL);
		positionVo.setStatus(IPPositionVO.STATUS_VALIDATE);
		positionVo.setUnit(unitVo);
		positionVo.setCreatorId(unitVo.getCreatorId());
		positionVo.setCreatedTimestamp(unitVo.getCreatedTimestamp());

		IRoleService roleService = (IRoleService) getBean(IRoleService.BEAN_ID);
		positionVo.setRole(roleService.getDefaultRole());
		save(positionVo);
		return positionVo;
	}

	public IPPositionVO update(IPPositionVO positionVo) throws ServiceException {
		IServerTime serverTime = (IServerTime) getBean(IServerTime.BEAN_ID);
		try {
			positionVo.setLastModifiedTimestamp(serverTime.getServerDateTime());
			checkPosition(positionVo);
		} catch (CommonException e) {
			throw new ServiceException(e);
		}
		super.update_Hibernate_Object(positionVo);
		SessionUserHolder suser = (SessionUserHolder)getBean("sessionUserHolder");
		if(IPPositionVO.DEL_FLAG_DELETED.equals(positionVo.getDelFlag())){
			logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_ORG_MAINTAIN,  IPAuditLogVO.OP_CODE_DELETE, suser.getStaffId(), suser
				.getLoginIp(), PropertyUtil
				.getPropertyByKey(MODEL_Name) + IPAuditLogVO.SEPARATE + positionVo.getPositionid()+IPAuditLogVO.SEPARATE+positionVo.getPositionName());
		}else{
			logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_ORG_MAINTAIN,  IPAuditLogVO.OP_CODE_UPDATE, suser.getStaffId(), suser
					.getLoginIp(), PropertyUtil
					.getPropertyByKey(MODEL_Name) + IPAuditLogVO.SEPARATE + positionVo.getPositionid()+IPAuditLogVO.SEPARATE+positionVo.getPositionName());
		}
		return positionVo;
	}

	public int delete(IPPositionVO position) throws ServiceException {
		position.setDelFlag(IPPositionVO.DEL_FLAG_DELETED);
		update(position);
		return 1;
	}

	public void saveDefaultDuty(List staffs, List units) throws ServiceException {
		for (Iterator itUnit = units.iterator(); itUnit.hasNext();) {
			SCUnitProfileVO unitVo = (SCUnitProfileVO) itUnit.next();
			IPPositionVO positionVo = getDefaultPosition(unitVo);
			if (positionVo == null) {
				logger.warn("Unable to find default position in unit " + unitVo);
				continue;
			}
			for (Iterator itStaff = staffs.iterator(); itStaff.hasNext();) {
				SCUserProfileVO staffVo = (SCUserProfileVO) itStaff.next();
				IPDutyVO dutyVo = new IPDutyVO();
				dutyVo.setPosition(positionVo);
				dutyVo.setStaff(staffVo);
				if (save(dutyVo) == null) {
					logger.debug("Duty info exist " + dutyVo);
				}
			}
		}
	}

	public IPDutyVO save(IPDutyVO dutyVo) throws ServiceException {
		if (isDuplicated(dutyVo)) {
			return null;
		}
		
		//如果系统中存在对应设置且为删除状态，则恢复其为未删除状态
		String poid = getDutyHasDel(dutyVo);
		if(poid!=null){
			dutyVo.setDutyky(poid);
			dutyVo.setDelFlag("n");
			dutyVo.setStatus(IPDutyVO.STATUS_VALIDATE);
			super.update_Hibernate_Object(dutyVo);
		}else{
			IPKGenerator keyGen = (IPKGenerator) getBean(IPKGenerator.BEAN_ID);
			IServerTime serverTime = (IServerTime) getBean(IServerTime.BEAN_ID);

			try {
				dutyVo.setDutyky(keyGen.getUUIDKey(dutyVo));
				dutyVo.setDelFlag("n");
				dutyVo.setStatus(IPDutyVO.STATUS_VALIDATE);
				// TODO 保存创建人
				dutyVo.setCreatedTimestamp(serverTime.getServerDateTime());
			} catch (CommonException e) {
				throw new ServiceException(e);
			}
			super.save_Hibernate_Object(dutyVo);
			SessionUserHolder suser = (SessionUserHolder)getBean("sessionUserHolder");
			logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_ORG_MAINTAIN,  IPAuditLogVO.OP_CODE_SAVE, suser.getStaffId(), suser
					.getLoginIp(), PropertyUtil
					.getPropertyByKey(MODEL_Name) + IPAuditLogVO.SEPARATE + dutyVo.getPosition());
		}
		return dutyVo;
	}

	private boolean isDuplicated(IPDutyVO dutyVo) throws ServiceException {
		List l = find_iBatis("org.getDuplicatedDutyCount", dutyVo);
		if (l != null && l.size() > 0) {
			return (((Integer) l.get(0)).intValue() > 0);
		}
		return false;
	}
	
	private String getDutyHasDel(IPDutyVO dutyVo) throws ServiceException {
		List l = find_iBatis("org.getDutyHasDel", dutyVo);
		if (l != null && l.size() > 0) {
			return (String) l.get(0);
		}
		return null;
	}

	public IPPositionVO getDefaultPosition(SCUnitProfileVO unitVo) throws ServiceException {
		List l = find_iBatis("org.getDefaultPositionByUnit", unitVo);
		if (l.size() > 0) {
			return (IPPositionVO) l.get(0);
		}
		return null;
	}

	public void batchCommitDuty(IPPositionVO position, List insertList, List deleteList) throws ServiceException {
		for (Iterator itStaff = insertList.iterator(); itStaff.hasNext();) {
			SCUserProfileVO staffVo = (SCUserProfileVO) itStaff.next();
			IPDutyVO dutyVo = new IPDutyVO();
			dutyVo.setPosition(position);
			dutyVo.setStaff(staffVo);
			if (save(dutyVo) == null) {
				logger.debug("Duty info exist " + dutyVo);
			}
		}

		for (Iterator itStaff = deleteList.iterator(); itStaff.hasNext();) {
			SCUserProfileVO staffVo = (SCUserProfileVO) itStaff.next();
			IPDutyVO dutyVo = new IPDutyVO();
			dutyVo.setPosition(position);
			dutyVo.setStaff(staffVo);
			update_iBatis("org.deleteDuty", new Object[] { dutyVo });
			SessionUserHolder suser = (SessionUserHolder)getBean("sessionUserHolder");
			logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_ORG_MAINTAIN,  IPAuditLogVO.OP_CODE_DELETE, suser.getStaffId(), suser
					.getLoginIp(), PropertyUtil
					.getPropertyByKey(MODEL_Name) + IPAuditLogVO.SEPARATE + dutyVo.getPosition());
		}
	}

	public void batchCommitDuty(SCUserProfileVO staff, List insertList, List deleteList) throws ServiceException {
		for (Iterator itPos = insertList.iterator(); itPos.hasNext();) {
			IPPositionVO posVo = (IPPositionVO) itPos.next();
			IPDutyVO dutyVo = new IPDutyVO();
			dutyVo.setPosition(posVo);
			dutyVo.setStaff(staff);
			if (save(dutyVo) == null) {
				logger.debug("Duty info exist " + dutyVo);
			}
		}

		for (Iterator itPos = deleteList.iterator(); itPos.hasNext();) {
			IPPositionVO posVo = (IPPositionVO) itPos.next();
			IPDutyVO dutyVo = new IPDutyVO();
			dutyVo.setPosition(posVo);
			dutyVo.setStaff(staff);
			update_iBatis("org.deleteDuty", new Object[] { dutyVo });
			SessionUserHolder suser = (SessionUserHolder)getBean("sessionUserHolder");
			logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_ORG_MAINTAIN,  IPAuditLogVO.OP_CODE_DELETE, suser.getStaffId(), suser
					.getLoginIp(), PropertyUtil
					.getPropertyByKey(MODEL_Name) + IPAuditLogVO.SEPARATE + dutyVo.getPosition());
		}
	}

	public List getPositionsByStaff(SCUserProfileVO userProfile, SCUnitProfileVO unitProfile) throws ServiceException {
		if (userProfile == null) {
			return new ArrayList();
		}
		if (unitProfile == null) {
			return getPositionsByStaff(userProfile);
		}

		Map para = new HashMap();
		para.put("staffid", userProfile.getLogicalKey());
		para.put("unitid", unitProfile.getLogicalKey());
		List l = find_iBatis("org.getPositionsByStaffAndUnit", para);
		return l != null ? l : new ArrayList();
	}

	public List getPositionsByStaff(SCUserProfileVO staff) throws ServiceException {
		if (staff == null) {
			return new ArrayList();
		}
		List l = find_iBatis("org.getPositionsByStaff", staff);
		return l != null ? l : new ArrayList();
	}
	
	public List getRolesByStaff(SCUserProfileVO staff) throws ServiceException {
		if (staff == null) {
			return new ArrayList();
		}
		List l = find_iBatis("org.getRolesByStaff", staff);
		return l != null ? l : new ArrayList();
	}

	public List getPositionsByOwnerUnit(SCUnitProfileVO ownerUnit) throws ServiceException {
		return getPositionsByOwnerUnit(ownerUnit, 0, 9999);
	}

	public List getPositionsByOwnerUnit(SCUnitProfileVO unit, int offset, int pageSize) throws ServiceException {
		if (unit == null) {
			return new ArrayList(0);
		}
		return find_iBatis("org.getPositionsByOwnerUnit", unit, offset, pageSize);
	}

	public int getPositionCountByOwnerUnit(SCUnitProfileVO unit) throws ServiceException {
		List l = find_iBatis("org.getPositionCountByOwnerUnit", unit);
		if (l != null && l.size() > 0) {
			return ((Integer) l.get(0)).intValue();
		}
		return 0;
	}

	public List getPositionsByUnitSelectByStaff(SCUnitProfileVO unitProfile, SCUserProfileVO userProfile, int offset, int pageSize) throws ServiceException {
		Map m = new HashMap();
		if (unitProfile != null) {
			m.put("unitid", unitProfile.getLogicalKey());
		}

		if (userProfile != null) {
			m.put("staffid", userProfile.getLogicalKey());
		}
		return find_iBatis("org.getPositionsByUnitSelectByStaff", m, offset, pageSize);
	}

	public int getPositionCountByUnitSelectByStaff(SCUnitProfileVO unit, SCUserProfileVO staff) throws ServiceException {
		return getPositionCountByUnit(unit);
	}

	public List query(Map params, int offset, int pageSize)
			throws ServiceException {
		// TODO Auto-generated method stub
		return 	find_iBatis("org.queryPosition", params, offset, pageSize);
	}

	public int queryCount(Map params) throws ServiceException {
		// TODO Auto-generated method stub
		List l = find_iBatis("org.queryPositionCount", params);
		if (l != null && !l.isEmpty()) {
			return ((Integer) l.get(0)).intValue();
		}
		return 0;
	}
	
	public boolean isExist(String positioncode) throws ServiceException {
	    String sql = "from IPPositionVO";    
	    HqlWrapper wrapper = new HqlWrapper();
	    wrapper.setCondition("positionCode", HqlWrapper.EQUAL, positioncode);
	    String[] propertyNames = StringUtil.listToStrArray(wrapper
	        .getPropertyNames());
	    String[] operators = StringUtil.listToStrArray(wrapper
	        .getOperators());
	    List valuesList = wrapper.getValues();
	    Object[] values = valuesList == null || valuesList.size() == 0 ? null
	        : valuesList.toArray();
	    String orderBy = null;
	    String groupBy = null;
	    String otherCause = null;
	    Object[] result = this.find_Hibernate_ComposedHQL(sql, propertyNames, operators,
	        values, 0, 999999, true, orderBy, groupBy, otherCause);
	    List l = (ArrayList)result[0];
		if (l.size()>0){				
			return true;
		} 
		return false;				
}

	public List getPublicPosition() throws ServiceException {
		Map m = new HashMap();
		List l = find_iBatis("org.getPublicPositions", m);
		return l;
	}

	public boolean isHasAdminPosition(String staffid) throws ServiceException {
		int result=0;
		List l = find_iBatis("org.isHasAdminPosition", staffid);
		if (l != null && !l.isEmpty() && l.size()>0 ) {
			result = ( (Integer) l.get(0)).intValue();
		}
		if( result>0 ){
			return true;
		}
		return false;
	}

	public ILogDataService getLogDataService() {
		return logDataService;
	}

	public void setLogDataService(ILogDataService logDataService) {
		this.logDataService = logDataService;
	}

	public List getAllPositions() throws ServiceException {
		return this.findAll_Hibernate_ComposedHQL(" from IPPositionVO where DELFLAG='n' and unit.unitid <> 'virtualorg00000000' ");
	}
	
	public List getAllUndeletedPositions() throws ServiceException {
		return this.findAll_Hibernate_ComposedHQL(" from IPPositionVO where DELFLAG='n' ");
	}

	public List queryUnit(HashMap map) throws ServiceException {
		return this.find_iBatis("org.queryGridPosition", map);
	}

	public List getAllPositionsByRole() throws ServiceException {
		return this.findAll_Hibernate_ComposedHQL(" from IPPositionVO where DELFLAG='n' and unit.unitid = 'virtualorg00000000' ");
	}
	
	public List queryUnitByRole(HashMap map) throws ServiceException {
		return this.find_iBatis("org.queryGridPositionByRole", map);
	}
	
	public List getBackPositions(HashMap map, int offset, int pageSize) throws ServiceException {
		return find_iBatis("org.getBackPositions", map, offset, pageSize);
	}
	
	public int getBackPositionsCount(HashMap map) throws ServiceException {
		List countList =  find_iBatis("org.getBackPositionsCount", map);
		if (!countList.isEmpty()) {
			return ((Integer) countList.get(0)).intValue();
		}
		return 0;
	}
	
	public String saveBackToPosition(List backBeans) throws ServiceException ,CommonException{
		int result = 0;
		
		if (backBeans != null) {
			for (Iterator it = backBeans.iterator(); it.hasNext();) {
				IPPositionVO ips = (IPPositionVO) it.next();	
				updateBackPosition(ips);			
				result++;
			}
		}
		return "true";
	}
	
	public String saveFullDel(List delBeans) throws ServiceException ,CommonException{
		int result = 0;
		
		if (delBeans != null) {
			for (Iterator it = delBeans.iterator(); it.hasNext();) {
				IPPositionVO ips = (IPPositionVO) it.next();	
				delFullPosition(ips);
				result++;
			}
		}
		return "true";
	}

	private void updateBackPosition(IPPositionVO position) throws ServiceException,
			CommonException {
		position.setDelFlag(IPPositionVO.DEL_FLAG_NORMAL);
		update(position);
		SessionUserHolder suser = (SessionUserHolder)getBean("sessionUserHolder");
		logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_ORG_MAINTAIN,  IPAuditLogVO.OP_CODE_UPDATE, suser.getStaffId(), suser
				.getLoginIp(), PropertyUtil.getPropertyByKey(AppConstants.MSG_INFO_APP_3002) + IPAuditLogVO.SEPARATE + position.getPositionid()+IPAuditLogVO.SEPARATE+position.getPositionName());
	}
	
	private void delFullPosition(IPPositionVO position) throws ServiceException,
			CommonException {
		position.setRole(null);
		position.setUnit(null);
		super.delete_Hibernate_Object(position);
		SessionUserHolder suser = (SessionUserHolder) getBean("sessionUserHolder");
		logDataService.saveLog(IPAuditLogVO.BIZ_TYPE_ORG_MAINTAIN, IPAuditLogVO.OP_CODE_DELETE, suser.getStaffId(),
				suser.getLoginIp(), PropertyUtil.getPropertyByKey(MODEL_Name));
	}
}
